package cleancode.controller.methodinvoker;

import java.lang.reflect.Method;

import cleancode.controller.commandexecutor.CommandExecutor;
import cleancode.controller.interpreter.CommandInfo;
import cleancode.model.Operation;

/**
 * Mapping command info to the methods of commandHandler.
 */
public class DefaultOperationMethodInvoker implements OperationMethodInvoker
{
    private CommandExecutor commandExecutor;

    private Method[] methods;

    public DefaultOperationMethodInvoker( CommandExecutor executor )
    {
        commandExecutor = executor;
        methods = executor.getClass().getDeclaredMethods();
    }

    public String invoke( CommandInfo commandInfo )
    {
        Method method = getMethodForOperation( commandInfo.getOperation() );
        Object returnValue = null;
        try
        {
            returnValue = method.invoke( commandExecutor, commandInfo.getArgs() );
            if( !( returnValue instanceof String ) )
            {
                returnValue = "Done!";
            }
        }
        catch( Exception e )
        {
            returnValue = "Error occurred when executing " + commandInfo.getCommand() + "!" + "\n" + e;
        }
        return ( String ) returnValue;
    }

    private Method getMethodForOperation( Operation operation )
    {
        String operationName = operation.getName();
        for( Method method : methods )
        {
            if( operationName.equals( method.getName() ) )
            {
                return method;
            }
        }
        return null;
    }
}
